#
# Ivan Vidal
# Roberto Andrino
# -*- coding: cp1252 -*-
from SimPy.Simulation import *
#
#  en este ejemplo se usaran cuatro recursos para simular cuatro ventanillas
#  de atencion en un banco. Los clientes hacen cola en esas ventanillas para ser
#  atendidos. Por ello, cuando llega un cliente puede seleccionar la ventanilla
#  que tiene la cola más corta.

#  los atributos de un resource R:
#     R.waitQ  elementos que estan haciendo
#             cola para utilizar el recuros.
#     R.activeQ  elementos que estan siendo
#             atendidos por este recurso.

from random import uniform
from random import Random, randint
class Car(Process):
    
    def __init__(self,id):
        Process.__init__(self)
        self.id=id
        
    def carDriving(self,driveTime,parkTime):
        yield hold,self,driveTime
        self.llega = now()
        # ahora decide que puerta usara para ingresar:
        # aquella que tenga menor número de clientes en su cola

        carrosxPuerta = [ len(gates[0].waitQ) + len(gates[0].activeQ),len(gates[1].waitQ) + len(gates[1].activeQ) ,len(gates[2].waitQ) + len(gates[2].activeQ),len(gates[3].waitQ) + len(gates[3].activeQ)]
        
        for i in range(4): #hay cuatro ventanillas
            if carrosxPuerta[i] == 0 or carrosxPuerta[i] == min(carrosxPuerta):
                self.puerta = i  #escogemos la ventanilla que no tiene clientes o
                            # cuya cola es la menor
                break

        print " el cliente ",self.id," hace cola en ventanilla ", self.puerta
        print "%5.1f %s empieza cola en ventanilla %d" %(now(),self.id, self.puerta)
        yield request,self,gates[self.puerta] #esperamos pasar por la ventanilla
        print "%5.1f %s entra ventanilla %d" %(now(),self.id, self.puerta)
        
    
        # ya esta en la ventanilla, ahora a hacer la transaccion:
        yield request,self,parkingLot 
        print "%5.1f %s haciendo transaccion " %(now(),self.id)
        yield hold,self,parkTime
        tiempoTotal = now() - self.llega
        wt.observe(tiempoTotal)
        print "%5.1f %s transaccion hecha despues de  %5.1f  tiempo en el banco = %5.1f" %(now(),self.id,parkTime,tiempoTotal)
        yield release,self,parkingLot 
    
        yield release, self, gates[self.puerta]
        
        
wt=Monitor()
initialize()
nrCars=25
parkingLot=Resource(capacity=4,qType=FIFO)
#ahora definimos las cuatro ventanillas, como recursos. Las colocamos
#en una lista, por si en el futuro definimos más ventanillas.
gates = [Resource(capacity=1,name="ventanilla 1"), Resource(capacity=1,name="ventanilla 2"),Resource(capacity=1,name="ventanilla 3"), Resource(capacity=1,name="ventanilla 4"), Resource(capacity=1,name="ventanilla 5")]
r = Random(12345)

for i in range(nrCars):
    c=Car(id="cli "+ str(i))
    activate(c,c.carDriving(driveTime=r.randint(1,50),parkTime=r.randint(1,50)))
simulate(until=1000)

print "Tiempo total en la U: \tmean = %5.1f, \n\t\tvariance=%2d"%(wt.mean(),wt.var())





